﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Service.Framework.AppStartup;
using Service.Framework.Model;
using Service.Framework.Utils;

namespace Service.Framework
{
    public static class App
    {
        private static IServiceCollection? _serviceCollection;

        private static IHost? _host;

        private static IHttpContextAccessor? _httpContextAccessor;

        private static readonly List<IStartupModule> _startups = new List<IStartupModule>();


        private static readonly List<string> _urls = new List<string>();

        private static WebApplication? _webApplication;

        private static WebApplicationBuilder? _webApplicationBuilder;

        private static readonly AppOptions _appOptions = new AppOptions();

        //
        // 摘要:
        //     IServiceCollection
        public static IServiceCollection? Services => _serviceCollection;

        //
        // 摘要:
        //     IHost
        public static IHost? Host => _host;

        //
        // 摘要:
        //     HttpContext
        public static HttpContext? HttpContext => _httpContextAccessor?.HttpContext;

        //
        // 摘要:
        //     IServiceProvider
        public static IServiceProvider? ServiceProvider => _host?.Services;

        //
        // 摘要:
        //     程序启动器集合
        public static IStartupModule[] Startups => _startups.ToArray();


        //
        // 摘要:
        //     程序启动地址
        public static string[] Urls => _urls.ToArray();

        //
        // 摘要:
        //     WebApplication
        public static WebApplication? WebApplication => _webApplication;

        //
        // 摘要:
        //     WebApplicationBuilder
        public static WebApplicationBuilder? WebApplicationBuilder => _webApplicationBuilder;

        //
        // 摘要:
        //     App 配置项
        public static AppOptions AppOptions => _appOptions;


        //
        // 摘要:
        //     添加  framework
        //
        // 参数:
        //   builder:
        //
        //   options:
        //
        // 类型参数:
        //   TStartupModule:
        public static WebApplicationBuilder AddFramework<TStartupModule>(this WebApplicationBuilder builder, Action<AppOptions>? options = null) where TStartupModule : IStartupModule
        {
            _webApplicationBuilder = builder;
            _serviceCollection = builder.Services;
            if (Activator.CreateInstance(typeof(TStartupModule)) is IStartupModule startupModule)
            {
                _startups.Clear();
                List<IStartupModule> list = (startupModule?.GetAllImportStartup())?.OrderBy((IStartupModule w) => w.Order).ToList();
                if (list != null && list.Count > 0)
                {
                    _startups.AddRange(list);
                }

                foreach (IStartupModule startup in _startups)
                {
                    startup?.ConfigureServices(builder);
                }
            }
            options?.Invoke(_appOptions);
            _appOptions.WebApplicationBuilderAction?.Invoke(builder);
            return builder;
        }

        //
        // 摘要:
        //     开始启动 hzy framework
        //
        // 参数:
        //   app:
        public static async Task StartFrameworkAsync(this WebApplication app)
        {
            WebApplication app2 = app;
            _webApplication = app2;
            IHostApplicationLifetime hostApplicationLifetime = app2.Services.GetService<IHostApplicationLifetime>();
            if (hostApplicationLifetime == null)
            {
                return;
            }

            hostApplicationLifetime.ApplicationStarted.Register(delegate
            {
                _urls.AddRange(app2.Urls.ToList());
                foreach (IStartupModule startup in _startups)
                {
                    startup?.ApplicationStarted(app2);
                }
            });
            hostApplicationLifetime.ApplicationStopping.Register(delegate
            {
                foreach (IStartupModule startup2 in _startups)
                {
                    startup2?.ApplicationStopping(app2);
                }
            });
            hostApplicationLifetime.ApplicationStopped.Register(delegate
            {
                foreach (IStartupModule startup3 in _startups)
                {
                    startup3?.ApplicationStopped(app2);
                }
            });
            _httpContextAccessor = app2.Services.GetService<IHttpContextAccessor>();
            _host = app2;
            foreach (IStartupModule startup4 in _startups)
            {
                startup4?.Configure(app2);
            }

            _appOptions?.WebApplicationAction?.Invoke(app2);
            await app2.RunAsync();
        }

    }
}
